#include <iostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <memory>
#include <sstream>
#include <chrono>
#include <iomanip>
#include <random>

// 聊天类型
enum ChatType {
    CHAT_PRIVATE = 1,    // 单聊
    CHAT_GROUP = 2       // 群聊
};

// 增强的消息类型
enum EnhancedMessageType {
    MSG_LOGIN = 1,
    MSG_LOGOUT = 2,
    MSG_PRIVATE_CHAT = 3,        // 私聊消息
    MSG_GROUP_CHAT = 4,          // 群聊消息
    MSG_CREATE_GROUP = 5,        // 创建群组
    MSG_JOIN_GROUP = 6,          // 加入群组
    MSG_LEAVE_GROUP = 7,         // 离开群组
    MSG_INVITE_TO_GROUP = 8,     // 邀请入群
    MSG_USER_LIST = 9,           // 用户列表
    MSG_GROUP_LIST = 10,         // 群组列表
    MSG_CHAT_HISTORY = 11,       // 聊天记录
    MSG_USER_STATUS = 12,        // 用户状态
    MSG_ERROR = 13
};

// 群组角色
enum GroupRole {
    ROLE_MEMBER = 1,
    ROLE_ADMIN = 2,
    ROLE_OWNER = 3
};

struct Message {
    std::string from;
    std::string to;
    std::string groupId;
    std::string content;
    std::string timestamp;
    ChatType chatType;
    
    Message(const std::string& f, const std::string& c, ChatType type = CHAT_PRIVATE) 
        : from(f), content(c), chatType(type) {
        auto now = std::chrono::system_clock::now();
        auto time = std::chrono::system_clock::to_time_t(now);
        std::stringstream ss;
        ss << std::put_time(std::localtime(&time), "%H:%M:%S");
        timestamp = ss.str();
    }
    
    Message(const std::string& f, const std::string& t, const std::string& c) 
        : from(f), to(t), content(c), chatType(CHAT_PRIVATE) {
        auto now = std::chrono::system_clock::now();
        auto time = std::chrono::system_clock::to_time_t(now);
        std::stringstream ss;
        ss << std::put_time(std::localtime(&time), "%H:%M:%S");
        timestamp = ss.str();
    }
};

struct GroupInfo {
    std::string groupId;
    std::string groupName;
    std::string description;
    std::string ownerId;
    std::unordered_set<std::string> admins;
    std::unordered_set<std::string> members;
    int maxMembers;
    std::vector<Message> messages;
    
    GroupInfo(const std::string& id, const std::string& name, const std::string& owner)
        : groupId(id), groupName(name), ownerId(owner), maxMembers(500) {
        members.insert(owner);  // 群主自动成为成员
    }
    
    bool isMember(const std::string& userId) const {
        return members.find(userId) != members.end();
    }
    
    bool isAdmin(const std::string& userId) const {
        return admins.find(userId) != admins.end() || userId == ownerId;
    }
    
    bool addMember(const std::string& userId) {
        if (members.size() >= maxMembers) return false;
        members.insert(userId);
        return true;
    }
    
    void removeMember(const std::string& userId) {
        members.erase(userId);
        admins.erase(userId);
    }
    
    void showInfo() const {
        std::cout << "\n📊 群组信息:" << std::endl;
        std::cout << "  🏷️  群组名: " << groupName << std::endl;
        std::cout << "  🆔 群组ID: " << groupId << std::endl;
        std::cout << "  👑 群主: " << ownerId << std::endl;
        std::cout << "  👥 成员数: " << members.size() << "/" << maxMembers << std::endl;
        if (!description.empty()) {
            std::cout << "  📝 描述: " << description << std::endl;
        }
        
        std::cout << "  👤 成员列表: ";
        for (const auto& member : members) {
            std::cout << member;
            if (member == ownerId) std::cout << "(群主)";
            else if (admins.find(member) != admins.end()) std::cout << "(管理员)";
            std::cout << " ";
        }
        std::cout << std::endl;
    }
    
    void showHistory() const {
        std::cout << "\n📋 群聊记录 [" << groupName << "]:" << std::endl;
        std::cout << std::string(60, '-') << std::endl;
        if (messages.empty()) {
            std::cout << "  暂无聊天记录" << std::endl;
        } else {
            for (const auto& msg : messages) {
                std::cout << "[" << msg.timestamp << "] " << msg.from 
                         << ": " << msg.content << std::endl;
            }
        }
        std::cout << std::string(60, '-') << std::endl;
    }
};

class GroupChatSystem {
private:
    std::unordered_map<std::string, bool> users; // username -> isOnline
    std::unordered_map<std::string, std::shared_ptr<GroupInfo>> groups; // groupId -> group
    std::unordered_map<std::string, std::unordered_set<std::string>> userGroups; // userId -> groupIds
    
    std::string generateId() {
        static std::random_device rd;
        static std::mt19937 gen(rd());
        static std::uniform_int_distribution<> dis(1000, 9999);
        
        auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count();
        
        return std::to_string(now % 1000000) + "_" + std::to_string(dis(gen));
    }
    
public:
    bool login(const std::string& username) {
        if (username.empty()) {
            std::cout << "❌ 用户名不能为空" << std::endl;
            return false;
        }
        
        users[username] = true;
        if (userGroups.find(username) == userGroups.end()) {
            userGroups[username] = std::unordered_set<std::string>();
        }
        std::cout << "✅ " << username << " 登录成功！" << std::endl;
        return true;
    }
    
    std::string createGroup(const std::string& groupName, const std::string& ownerId, const std::string& description = "") {
        if (users.find(ownerId) == users.end() || !users[ownerId]) {
            std::cout << "❌ 创建者 " << ownerId << " 未登录" << std::endl;
            return "";
        }
        
        std::string groupId = generateId();
        auto group = std::make_shared<GroupInfo>(groupId, groupName, ownerId);
        group->description = description;
        
        groups[groupId] = group;
        userGroups[ownerId].insert(groupId);
        
        std::cout << "🏠 群组创建成功: " << groupName << " (ID: " << groupId << ")" << std::endl;
        std::cout << "👑 群主: " << ownerId << std::endl;
        return groupId;
    }
    
    bool joinGroup(const std::string& groupId, const std::string& userId) {
        if (users.find(userId) == users.end() || !users[userId]) {
            std::cout << "❌ 用户 " << userId << " 未登录" << std::endl;
            return false;
        }
        
        auto groupIt = groups.find(groupId);
        if (groupIt == groups.end()) {
            std::cout << "❌ 群组 " << groupId << " 不存在" << std::endl;
            return false;
        }
        
        auto group = groupIt->second;
        if (group->isMember(userId)) {
            std::cout << "❌ " << userId << " 已经是群成员" << std::endl;
            return false;
        }
        
        if (!group->addMember(userId)) {
            std::cout << "❌ 群组已满，无法加入" << std::endl;
            return false;
        }
        
        userGroups[userId].insert(groupId);
        
        // 发送系统消息
        Message joinMsg("系统", userId + " 加入了群组", CHAT_GROUP);
        joinMsg.groupId = groupId;
        group->messages.push_back(joinMsg);
        
        std::cout << "✅ " << userId << " 成功加入群组: " << group->groupName << std::endl;
        return true;
    }
    
    bool leaveGroup(const std::string& groupId, const std::string& userId) {
        auto groupIt = groups.find(groupId);
        if (groupIt == groups.end()) {
            std::cout << "❌ 群组 " << groupId << " 不存在" << std::endl;
            return false;
        }
        
        auto group = groupIt->second;
        if (!group->isMember(userId)) {
            std::cout << "❌ " << userId << " 不是群成员" << std::endl;
            return false;
        }
        
        if (group->ownerId == userId) {
            std::cout << "❌ 群主不能离开群组，只能解散群组" << std::endl;
            return false;
        }
        
        group->removeMember(userId);
        userGroups[userId].erase(groupId);
        
        // 发送系统消息
        Message leaveMsg("系统", userId + " 离开了群组", CHAT_GROUP);
        leaveMsg.groupId = groupId;
        group->messages.push_back(leaveMsg);
        
        std::cout << "✅ " << userId << " 成功离开群组: " << group->groupName << std::endl;
        return true;
    }
    
    bool sendGroupMessage(const std::string& groupId, const std::string& fromUser, const std::string& content) {
        if (users.find(fromUser) == users.end() || !users[fromUser]) {
            std::cout << "❌ 发送者 " << fromUser << " 未登录" << std::endl;
            return false;
        }
        
        auto groupIt = groups.find(groupId);
        if (groupIt == groups.end()) {
            std::cout << "❌ 群组 " << groupId << " 不存在" << std::endl;
            return false;
        }
        
        auto group = groupIt->second;
        if (!group->isMember(fromUser)) {
            std::cout << "❌ " << fromUser << " 不是群成员，无法发送消息" << std::endl;
            return false;
        }
        
        Message msg(fromUser, content, CHAT_GROUP);
        msg.groupId = groupId;
        group->messages.push_back(msg);
        
        std::cout << "📤 群消息已发送: [" << msg.timestamp << "] " 
                 << fromUser << " -> " << group->groupName << ": " << content << std::endl;
        std::cout << "📡 消息已广播给 " << (group->members.size() - 1) << " 个成员" << std::endl;
        return true;
    }
    
    bool inviteToGroup(const std::string& groupId, const std::string& inviterId, const std::string& inviteeId) {
        auto groupIt = groups.find(groupId);
        if (groupIt == groups.end()) {
            std::cout << "❌ 群组 " << groupId << " 不存在" << std::endl;
            return false;
        }
        
        auto group = groupIt->second;
        if (!group->isAdmin(inviterId)) {
            std::cout << "❌ " << inviterId << " 无权限邀请他人入群" << std::endl;
            return false;
        }
        
        if (group->isMember(inviteeId)) {
            std::cout << "❌ " << inviteeId << " 已经是群成员" << std::endl;
            return false;
        }
        
        if (users.find(inviteeId) == users.end() || !users[inviteeId]) {
            std::cout << "❌ 被邀请用户 " << inviteeId << " 未登录" << std::endl;
            return false;
        }
        
        // 自动接受邀请（简化版）
        if (group->addMember(inviteeId)) {
            userGroups[inviteeId].insert(groupId);
            
            // 发送系统消息
            Message inviteMsg("系统", inviterId + " 邀请 " + inviteeId + " 加入了群组", CHAT_GROUP);
            inviteMsg.groupId = groupId;
            group->messages.push_back(inviteMsg);
            
            std::cout << "✅ " << inviterId << " 成功邀请 " << inviteeId << " 加入群组: " << group->groupName << std::endl;
            return true;
        } else {
            std::cout << "❌ 群组已满，无法邀请" << std::endl;
            return false;
        }
    }
    
    std::shared_ptr<GroupInfo> getGroup(const std::string& groupId) {
        auto it = groups.find(groupId);
        return (it != groups.end()) ? it->second : nullptr;
    }
    
    void showOnlineUsers() {
        std::cout << "\n👥 在线用户列表:" << std::endl;
        for (const auto& pair : users) {
            if (pair.second) {
                std::cout << "  🟢 " << pair.first << std::endl;
            }
        }
    }
    
    void showUserGroups(const std::string& userId) {
        std::cout << "\n📱 " << userId << " 的群组列表:" << std::endl;
        auto userGroupIt = userGroups.find(userId);
        if (userGroupIt == userGroups.end() || userGroupIt->second.empty()) {
            std::cout << "  暂无加入的群组" << std::endl;
            return;
        }
        
        for (const std::string& groupId : userGroupIt->second) {
            auto group = getGroup(groupId);
            if (group) {
                std::string role = "";
                if (group->ownerId == userId) role = "(群主)";
                else if (group->admins.find(userId) != group->admins.end()) role = "(管理员)";
                else role = "(成员)";
                
                std::cout << "  🏠 " << group->groupName << " " << role 
                         << " - " << group->members.size() << " 人" << std::endl;
            }
        }
    }
    
    void showAllGroups() {
        std::cout << "\n🏠 所有群组:" << std::endl;
        if (groups.empty()) {
            std::cout << "  暂无群组" << std::endl;
        } else {
            for (const auto& pair : groups) {
                auto group = pair.second;
                std::cout << "  📱 " << group->groupName << " (" << group->groupId << ")" 
                         << " - 群主: " << group->ownerId << " - " << group->members.size() << " 人" << std::endl;
            }
        }
    }
};

void showWelcome() {
    std::cout << "\n" << std::string(70, '=') << std::endl;
    std::cout << "    🏠 群聊演示系统 - 多人聊天体验" << std::endl;
    std::cout << std::string(70, '=') << std::endl;
    std::cout << "💡 支持创建群组、邀请成员、群组管理" << std::endl;
    std::cout << "✨ 群消息广播、聊天记录、权限管理" << std::endl;
}

void showCommands() {
    std::cout << "\n📋 可用命令:" << std::endl;
    std::cout << "  login <用户名>                     - 用户登录" << std::endl;
    std::cout << "  create <群名> <群主> [描述]        - 创建群组" << std::endl;
    std::cout << "  join <群ID> <用户名>               - 加入群组" << std::endl;
    std::cout << "  leave <群ID> <用户名>              - 离开群组" << std::endl;
    std::cout << "  send <群ID> <发送者> <消息>        - 发送群消息" << std::endl;
    std::cout << "  invite <群ID> <邀请者> <被邀请者>  - 邀请入群" << std::endl;
    std::cout << "  info <群ID>                        - 查看群组信息" << std::endl;
    std::cout << "  history <群ID>                     - 查看群聊记录" << std::endl;
    std::cout << "  mygroups <用户名>                  - 查看我的群组" << std::endl;
    std::cout << "  groups                             - 查看所有群组" << std::endl;
    std::cout << "  users                              - 查看在线用户" << std::endl;
    std::cout << "  demo                               - 运行自动演示" << std::endl;
    std::cout << "  help                               - 显示帮助" << std::endl;
    std::cout << "  quit                               - 退出程序" << std::endl;
}

void runAutoDemo(GroupChatSystem& chatSystem) {
    std::cout << "\n🎬 群聊自动演示开始..." << std::endl;
    
    // 1. 登录多个用户
    std::cout << "\n👥 步骤1: 用户登录系统" << std::endl;
    chatSystem.login("Alice");
    chatSystem.login("Bob");
    chatSystem.login("Charlie");
    chatSystem.login("David");
    
    // 2. 创建群组
    std::cout << "\n🏠 步骤2: 创建群组" << std::endl;
    std::string techGroup = chatSystem.createGroup("技术讨论群", "Alice", "讨论技术问题的群组");
    std::string gameGroup = chatSystem.createGroup("游戏交流群", "Bob", "一起游戏聊天");
    
    // 3. 邀请成员加入
    std::cout << "\n👋 步骤3: 邀请成员加入群组" << std::endl;
    chatSystem.joinGroup(techGroup, "Bob");
    chatSystem.joinGroup(techGroup, "Charlie");
    chatSystem.inviteToGroup(gameGroup, "Bob", "Alice");
    chatSystem.joinGroup(gameGroup, "David");
    
    // 4. 发送群消息
    std::cout << "\n💬 步骤4: 群聊交流" << std::endl;
    chatSystem.sendGroupMessage(techGroup, "Alice", "欢迎大家加入技术讨论群！");
    chatSystem.sendGroupMessage(techGroup, "Bob", "谢谢群主！有什么技术问题可以在这里讨论");
    chatSystem.sendGroupMessage(techGroup, "Charlie", "太好了，我正好有个问题想请教");
    
    chatSystem.sendGroupMessage(gameGroup, "Bob", "游戏群建立了，大家一起玩游戏吧！");
    chatSystem.sendGroupMessage(gameGroup, "Alice", "好的，什么时候开始？");
    chatSystem.sendGroupMessage(gameGroup, "David", "我也想参加！");
    
    // 5. 查看群组信息
    std::cout << "\n📊 步骤5: 查看群组信息" << std::endl;
    auto tech = chatSystem.getGroup(techGroup);
    if (tech) tech->showInfo();
    
    auto game = chatSystem.getGroup(gameGroup);
    if (game) game->showInfo();
    
    // 6. 查看聊天记录
    std::cout << "\n📋 步骤6: 查看聊天记录" << std::endl;
    if (tech) tech->showHistory();
    if (game) game->showHistory();
    
    // 7. 查看用户的群组列表
    std::cout << "\n👤 步骤7: 查看用户群组" << std::endl;
    chatSystem.showUserGroups("Alice");
    chatSystem.showUserGroups("Bob");
    
    std::cout << "\n🎉 群聊演示完成！" << std::endl;
}

std::vector<std::string> parseCommand(const std::string& input) {
    std::vector<std::string> tokens;
    std::istringstream iss(input);
    std::string token;
    
    while (iss >> token) {
        tokens.push_back(token);
    }
    
    return tokens;
}

int main() {
    GroupChatSystem chatSystem;
    showWelcome();
    showCommands();
    
    std::string input;
    while (true) {
        std::cout << "\n> ";
        std::getline(std::cin, input);
        
        if (input.empty()) continue;
        
        std::vector<std::string> tokens = parseCommand(input);
        if (tokens.empty()) continue;
        
        std::string command = tokens[0];
        
        if (command == "quit" || command == "exit") {
            std::cout << "👋 再见！" << std::endl;
            break;
        } else if (command == "help") {
            showCommands();
        } else if (command == "login" && tokens.size() >= 2) {
            chatSystem.login(tokens[1]);
        } else if (command == "create" && tokens.size() >= 3) {
            std::string description = "";
            if (tokens.size() >= 4) {
                for (size_t i = 3; i < tokens.size(); ++i) {
                    if (i > 3) description += " ";
                    description += tokens[i];
                }
            }
            chatSystem.createGroup(tokens[1], tokens[2], description);
        } else if (command == "join" && tokens.size() >= 3) {
            chatSystem.joinGroup(tokens[1], tokens[2]);
        } else if (command == "leave" && tokens.size() >= 3) {
            chatSystem.leaveGroup(tokens[1], tokens[2]);
        } else if (command == "send" && tokens.size() >= 4) {
            std::string message;
            for (size_t i = 3; i < tokens.size(); ++i) {
                if (i > 3) message += " ";
                message += tokens[i];
            }
            chatSystem.sendGroupMessage(tokens[1], tokens[2], message);
        } else if (command == "invite" && tokens.size() >= 4) {
            chatSystem.inviteToGroup(tokens[1], tokens[2], tokens[3]);
        } else if (command == "info" && tokens.size() >= 2) {
            auto group = chatSystem.getGroup(tokens[1]);
            if (group) {
                group->showInfo();
            } else {
                std::cout << "❌ 群组不存在: " << tokens[1] << std::endl;
            }
        } else if (command == "history" && tokens.size() >= 2) {
            auto group = chatSystem.getGroup(tokens[1]);
            if (group) {
                group->showHistory();
            } else {
                std::cout << "❌ 群组不存在: " << tokens[1] << std::endl;
            }
        } else if (command == "mygroups" && tokens.size() >= 2) {
            chatSystem.showUserGroups(tokens[1]);
        } else if (command == "groups") {
            chatSystem.showAllGroups();
        } else if (command == "users") {
            chatSystem.showOnlineUsers();
        } else if (command == "demo") {
            runAutoDemo(chatSystem);
        } else {
            std::cout << "❌ 未知命令或参数不足。输入 'help' 查看帮助。" << std::endl;
        }
    }
    
    return 0;
} 